package com.wan37.logic.global;

import com.google.protobuf.Message;
import com.wan37.logic.chat.handler.*;
import com.wan37.logic.domain.vo.MessageVO;
import com.wan37.logic.email.handler.CGameWorldPlayerEmailHandler;
import com.wan37.logic.guild.handler.CGameGuildHandler;
import com.wan37.logic.handler.MsgHandler;
import com.wan37.logic.handler.message.*;
import com.wan37.logic.shop.handler.CGameShopHandler;
import com.wan37.logic.task.handler.CGameTaskHandler;
import com.wan37.logic.team.handler.CGameTeamHandler;
import com.wan37.logic.trading.handler.CGameTradingHandler;
import com.wan37.logic.tradingshop.handler.CGameTradingShopHandler;
import com.wan37.protobuf.analysis.ParseMap;
import com.wan37.protobuf.message.client2server.game.*;
import com.wan37.protobuf.message.internal.Internal;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : luoyong
 * @date : 2020-05-28 09:46
 **/
public class HandlerManager {

    private static final Logger logger = LoggerFactory.getLogger(HandlerManager.class);

    /**
     * 保存msgHandler消息处理器的map.
     * key = msg对应的ptoNum的值, value = 对应的MsgHandler的构造函数对象
     */
    private static final Map<Integer, Constructor<? extends MsgHandler>> msgHandlerMap = new HashMap<>();


    /**
     * 向HandlerManager中注册消息以及对应的MsgHandler.
     *
     * @param messageClazz
     * @param msgHandlerClazz
     */
    public static void register(Class<? extends Message> messageClazz, Class<? extends MsgHandler> msgHandlerClazz) {

        //首先获得ptoNum
        int ptoNum = ParseMap.getPtoNum(messageClazz);
        //获得构造函数
        try {
            //获得构造函数
            Constructor<? extends MsgHandler> constructor = msgHandlerClazz.getConstructor(MessageVO.class);
            //添加到msgHandlerMap中
            msgHandlerMap.put(ptoNum, constructor);

        } catch (NoSuchMethodException e) {
            throw new RuntimeException("没有找到对应的构造函数", e);
        }

    }


    /**
     * 获得对应的MsgHandler消息处理器对象.
     *
     * @param ptoNum
     * @param userId
     * @param netId
     * @param message
     * @param ctx
     * @return
     */
    public static MsgHandler getMsgHandler(int ptoNum, String userId, long netId,
                                           Message message, ChannelHandlerContext ctx)
            throws IllegalAccessException, InvocationTargetException, InstantiationException {

        Constructor<? extends MsgHandler> constructor = msgHandlerMap.get(ptoNum);
        MessageVO messageVO = new MessageVO(userId, netId, message, ctx);
        if (constructor == null) {
            //没有
            logger.info("msgHandler not exist, ptoNum : {}", ptoNum);
            return null;
        }
        //有, 通过构造函数创建对象
        return constructor.newInstance(messageVO);
    }


    /**
     * 初始化各类消息的消息处理器.
     */
    public static void initMsgHandlers() {
        HandlerManager.register(Internal.Greet.class, GreetHandler.class);
        HandlerManager.register(Game.CGameMsg.class, CGameHandler.class);
        HandlerManager.register(Game.CGameMove.class, CGameMoveHandler.class);
        HandlerManager.register(Game.CGameAoi.class, CGameAoiHandler.class);
        HandlerManager.register(Game.CGameChatMsg.class, CGameChatHandler.class);
        HandlerManager.register(Game.CGameAttack.class, CGameAttackHandler.class);
        HandlerManager.register(Game.CGameSkillMsg.class, CGameSkillHandler.class);
        HandlerManager.register(Game.CGameRoleMsg.class, CGameRoleHandler.class);
        HandlerManager.register(GameBackpack.CGameWeaponryMsg.class, CGameWeaponryHandler.class);
        HandlerManager.register(GameBackpack.CGameItemMsg.class, CGameItemHandler.class);
        HandlerManager.register(Game.CGameUserLoginInitMsg.class, CGameUserLoginInitHandler.class);
        HandlerManager.register(Game.GGameUserLogoutMsg.class, GateUserLogoutHandler.class);
        HandlerManager.register(GameBossScene.CGameBossSceneMsg.class, CGameBossSceneHandler.class);
        HandlerManager.register(GameShop.CGameShopMsg.class, CGameShopHandler.class);
        HandlerManager.register(GameFighting.AutoFightingMsg.class, CGameAutoFightingHandler.class);
        HandlerManager.register(GameChat.OneToOneChat.class, CGameOneToOneChatHandler.class);
        HandlerManager.register(GameChat.OneToOneChatOld.class, CGameOneToOneChatOldHandler.class);
        HandlerManager.register(GameChat.WorldPlayerChat.class, CGameWorldPlayerChatHandler.class);
        HandlerManager.register(GameChat.WorldPlayerChatOld.class, CGameWorldPlayerChatOldHandler.class);
        HandlerManager.register(GameRole.CGameCreateRoleMsg.class, CGameCreatRoleHandler.class);
        HandlerManager.register(GameEmail.WorldPlayerEmailMsg.class, CGameWorldPlayerEmailHandler.class);
        HandlerManager.register(GameBossScene.CGamePvpSceneMsg.class, CGamePvpSceneHandler.class);
        HandlerManager.register(GameTeam.TeamMsg.class, CGameTeamHandler.class);
        HandlerManager.register(GameTrading.TradingMsg.class, CGameTradingHandler.class);
        HandlerManager.register(GameGuild.GuildMsg.class, CGameGuildHandler.class);
        HandlerManager.register(GameTradingShop.TradingShopMsg.class, CGameTradingShopHandler.class);
        HandlerManager.register(GameTask.TaskMsg.class, CGameTaskHandler.class);
    }
}

